So far, it has been sufficient for us to make a call
to an AJAX method and patiently await the response. At times, though, it
is handy to know a bit more about the HTTP request as it progresses. If
such a need arises, jQuery offers a suite of functions that can be used
to register callbacks when various AJAX-related events occur.
The .ajaxStart() and .ajaxStop()
methods are two examples of these observer functions, and can be
attached to any jQuery object. When an AJAX call begins with no other
transfer in progress, the .ajaxStart() callback is fired. Conversely, when the last active request ends, the callback attached with .ajaxStop() will be executed. All of the observers are global, in that they are called when any AJAX communication occurs, regardless of what code initiates it.
We can use these methods to
provide some feedback to the user in the case of a slow network
connection. The HTML for the page can have a suitable loading message
appended:
<div id="loading">
Loading...
</div>
This message is just a piece of arbitrary HTML; it could include an animated GIF image to provide a throbber,
for instance. In this case, we'll add a few simple styles to the CSS
file, so that when the message is displayed, the page looks like:
In keeping with the spirit of progressive enhancement,
however, we won't put this HTML markup directly on the page. It's only
relevant for us when JavaScript is available, so we will insert it using
jQuery:
$(document).ready(function() {
$('<div id="loading">Loading...</div>')
.insertBefore('#dictionary')
});
Our CSS file will give this<div> a display: none; style rule so that the message is initially hidden. To display it at the right time, we just register it as an observer with .ajaxStart():
$(document).ready(function() {
AJAX.ajaxStart() method$('<div id="loading">Loading...</div>')
.insertBefore('#dictionary')
.ajaxStart(function() {
$(this).show();
});
});
We can chain the hiding behavior right onto this:
$(document).ready(function() {
$('<div id="loading">Loading...</div>')
.insertBefore('#dictionary')
.ajaxStart(function() {
$(this).show();
}).ajaxStop(function() {
$(this).hide();
});
});
Voilà! We have our loading feedback.
Once again, note that these methods have no association with the particular ways in which the AJAX communications begin. The .load() attached to the A link and the attached to the B link both cause these actions to occur. .getJSON()
In this case, this global
behavior is desirable. If we need to get more specific, though, we have a
few options at our disposal. Some of the observer methods, like, send their callback a reference to the XMLHttpRequest
object. This can be used to differentiate one request from another, and
provide different behaviors. Other more specific handling can be
achieved by using the low-level $.ajax() function, which we'll discuss a bit later. .ajaxError()
The most common way of
interacting with the request, though, is the success callback, which we
have already covered. We have used this in several of our examples to
interpret the data coming back from the server and to populate the page
with the results. It can be used for other feedback too, of course.
Consider once again our example: .load()
$(document).ready(function() {
$('#letter-a a').click(function() {
$('#dictionary').load('a.html');
return false;
});
});
We can create a small enhancement here by making the loaded content fade into view rather than appear suddenly. The .load() can take a callback to be fired on completion:
$(document).ready(function() {
$('#letter-a a').click(function() {
$('#dictionary').hide().load('a.html', function() {
$(this).fadeIn();
});
return false;
});
});
First, we hide the
target element, and then initiate the load. When the load is complete,
we use the callback to show the newly-populated element by fading it in.